#pragma once

#include "io_mgr.h"
#include <unordered_map>
#include <string>
using std::string;
#include <mutex>
#include "util/threads.h"
#include "util/pevents.h"
#include "user_session.h"

/*
struct USER_AUTH_BLOCK
{
    string user_name;
    bool is_using_token;
    string login_token;
    string user_password;
}

struct UserStatistics
{
    time_t timeLogin;
    time_t timeLastRecv;
    time_t timeLastSnd;
    int64_t sendBytes;
    int64_t recvBytes;
}

struct MSESSION
{
    string session_id;      //< 会话ID，全服唯一值。
    CServerNode* pNet;      //< 收发数据。
    time_t lastActiveTime;  //< 最后一次收发数据的时间。
}
*/

#define EM_READ_EVENT  0x01
#define EM_ERROR_EVENT 0x02
#define EM_WRITE_EVENT 0x04
#define EM_CLOSE_EVENT 0x08
typedef unsigned int EventMask;


/**
 * @brief 在这里放和具体业务有关的代码，主要任务是处理收到的数据，根据这些数据处理业务逻辑
 * 并且向客户端返回响应。
 * 和网络收发有关的实现由CServerNode实现。
 * 注意在当前实现中notifySocketClosed和notifySocketError被调用时socket总是已经被关闭，但
 * 未来可能有所变动。
 */
class CNetIOManager : public IIOMgr
{
public:
    CNetIOManager();
    ~CNetIOManager();
public:
    void start();
    void stop();
public:
    //Implement IIOMgr
    virtual void newSocketAccepted(std::shared_ptr<CServerNode> node) override;
    virtual void notifySocketClosed(std::shared_ptr<CServerNode> node) override;
    virtual void notifySocketError(std::shared_ptr<CServerNode> node, int error_code) override;
    virtual void notifyDataRecvedEvent(std::shared_ptr<CServerNode> node) override;
    virtual void notifyDataSentEvent(std::shared_ptr<CServerNode> node) override;
private:
    static void *netIOThreadFunction(void* lp);
    void netIOThreadImpl();
    std::shared_ptr<IUserSession> find_session(std::shared_ptr<CServerNode> node);
    void set_session(std::shared_ptr<CServerNode> node, std::shared_ptr<IUserSession> session);
    void del_session(std::shared_ptr<CServerNode> node);
private:
    //std::unordered_map<int fd, USER_AUTH_BLOCK*> m_logining_users;     // 用户请求登录 -> 用户验证成功 -> 生成session -> 创建MSESSION -> 保存到m_sessions
    //std::unordered_map<std::string session, MSESSION*> m_sessions;    // Session,只有已登录用户才能使用我们的服务。
    // 将触发读、写、错误事件的连接对象缓存起来。
    std::recursive_mutex m_EventsMutex;
    std::unordered_map<std::shared_ptr<CServerNode>, EventMask> m_events;
    std::recursive_mutex m_sessions_mutex;
    std::unordered_map<std::shared_ptr<CServerNode>, std::shared_ptr<IUserSession>> m_sessions;
    qcutil::CThreadBase m_rsThread;
    qcutil::neosmart_event_t m_event_quit;
    qcutil::neosmart_event_t m_event_io;
    bool m_is_stopped;
};
